﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Reflection;
using System.ComponentModel.Design;

namespace ControlsLib
{
    public class DataFormControlHelper
    {
        public event EventHandler<ControlAddedEventArgs> ControlAdding;
        public event EventHandler<ControlAddedEventArgs> ControlAdded;

        private IDesignerHost m_designerHost = null;
        private object m_currentObject = null;
        private BindingSource m_bindingSource = null;

        public DataFormControlHelper(IDesignerHost designerHost, BindingSource bindingSource)
        {
            m_designerHost = designerHost;
            m_bindingSource = bindingSource;
        }

        public void LoadProperties(Type type, System.Windows.Forms.Control.ControlCollection controlCollection)
        {
            int step = 5;
            int leftOffset = 5;
            foreach (PropertyInfo pi in type.GetProperties())
            {
                //Label l = new Label();
                Label l = m_designerHost.CreateComponent(typeof(Label)) as Label;
                l.Location = new Point(leftOffset, step);
                l.Text = string.Format("{0}:", pi.Name);

                //
                
                //TextBox txt = new TextBox();
                Control txt = GetSpecificControl(pi.PropertyType);
                txt.Location = new Point(leftOffset + l.Width + 5, step);

                if (ControlAdding != null)
                {
                    ControlAdding(this, new ControlAddedEventArgs(txt));
                }

                // DataBinding...
                txt.DataBindings.Add(new Binding("Text", m_bindingSource, pi.Name));

                //
                step += l.Size.Height;

                //
                controlCollection.Add(l);
                controlCollection.Add(txt);

                if (ControlAdded != null)
                {
                    ControlAdded(this, new ControlAddedEventArgs(txt));
                }
            }
        }

        public static bool IsNumeric(Type type)
        {
            if (type == null)
                return false;
            if (type.IsEnum)
                return false;

            TypeCode typeCode = Type.GetTypeCode(type);

            switch (typeCode)
            {
                case TypeCode.Byte:
                case TypeCode.Decimal:
                case TypeCode.Double:
                case TypeCode.Int16:
                case TypeCode.Int32:
                case TypeCode.Int64:
                case TypeCode.SByte:
                case TypeCode.Single:
                case TypeCode.UInt16:
                case TypeCode.UInt32:
                case TypeCode.UInt64:
                    return true;
            }
            return false;
        }

        public Control GetSpecificControl(Type type)
        {
            Control retValue = new TextBox();

            try
            {
                if (type == typeof(DateTime))
                {
                    retValue = m_designerHost.CreateComponent(typeof(DateTimePicker)) as DateTimePicker;
                    //retValue = new DateTimePicker();
                    return retValue;
                }

                if (type == typeof(String))
                {
                    retValue = m_designerHost.CreateComponent(typeof(TextBox)) as TextBox;
                    //retValue = new TextBox();
                    return retValue;
                }

                if (type == typeof(Boolean))
                {
                    retValue = m_designerHost.CreateComponent(typeof(CheckBox)) as CheckBox;
                    //retValue = new CheckBox();
                    return retValue;
                }

                if (IsNumeric(type))
                {
                    retValue = m_designerHost.CreateComponent(typeof(NumericUpDown)) as NumericUpDown;
                    //retValue = new NumericUpDown();
                    return retValue;
                }

                if (type.IsEnum)
                {
                    retValue = m_designerHost.CreateComponent(typeof(ComboBox)) as ComboBox;
                    //retValue = new ComboBox();
                    return retValue;
                }
            }
            catch
            {
                retValue = m_designerHost.CreateComponent(typeof(TextBox)) as TextBox;
                //retValue = new TextBox();
                return retValue;
            }

            return retValue;
        }
    }
}
